module nade.tree_stack;

import nade.stack;


struct TreeStack!(T) {
	Stack!(Stack!(T))	_stack;


    void pushTrunk()
    {
		_stack.push;
    }

    void popTrunk(size_t num)
    {
		assert(_stack.length > num);
		_stack.pop(num);
    }
    T popTrunk()
    {
		assert(_stack.length > 1);
		return _stack.pop;
    }

    bool emptyTrunk()
    {
        return _stack.length > 1;
    }

    void clearTrunk()
    {
		_stack.pop(_stack.length - 1);
		clear();
    }

    size_t lengthTrunk()
    {
		return _stack.peek.length - 1;
    }
	size_t lengthTrunk(size_t rhs)
	{
		_stack.peek.length = rhs + 1;
		return rhs;
	}


    void push(T v)
    {
		_stack.peek.push();
    }
    void push(T[] vs)
    {
		_stack.peek.push(vs);
    }
    alias push opCatAssign;

    void pop(size_t num)
    {
		_stack.peek.pop(num);
    }

    T pop()
    {
		return _stack.peek.pop;
    }

    T peek()
    {
		return _stack.peek.peek;
    }

    bool empty()
    {
        return _stack.peek.empty;
    }

    void clear()
    {
		_stack.peek.clear;
    }

    size_t length()
    {
		return _stack.peek.length;
    }
	size_t length(size_t rhs)
	{
		return _stack.peek.length = rhs;
	}

    T[] array()
    {
        return _stack.array;
    }

    T opIndex(size_t i)
    {
        return _stack[i];
    }
    T opIndexAssign(T rhs, size_t i)
    {
        return _stack[i] = rhs;
    }

    Stack dup()
    {
        return TreeStack!(T)(_stack.dup);
    }

	bool contains(T element)
	{
		return _stack.peek.contains(element);
	}

	int opApply(int delegate(ref T) dg)
	{
		return _stack.peek.opApply(dg);
	}
	int opApplyReverse(int delegate(ref T) dg)
	{
		return _stack.peek.opApplyReverse(dg);
	}
}
